// import { Singleton } from "../decorate/Singleton";
// import { Constructor } from "../typed";

const { error, instantiate } = cc;

type onProgress = (finish: number, total: number, item: cc.AssetManager.RequestItem) => void;
type onComplete<T> = (error: Error, assets: T) => void;

// type AssetType<T = cc.Asset> = Constructor<T>;

// @Singleton
export class ResourceServices {
  public loadRes<T extends cc.Asset>(url: string, type: typeof cc.Asset) {
    //cc.log('[[[ load ]]]', url)
    return new Promise<T>((resolve, reject) => {
      if (type) {
        cc.resources.load(
          url,
          type,
          (error, asset) => {
            if (error) {
              cc.log("[spineLoader Error]" , error);
              reject(error);
            }
            resolve(asset as T);
          }
        );
      } else {
        cc.resources.load(url, (err, res) => {
          if (err) {
            error(err.message || err);
            reject(err.message);
            return;
          }
          resolve(res as T);
        });
      }
    });
  }
  
  public static loadJson<T>(fileName: string, callback: onComplete<T>) {
    cc.resources.load<cc.JsonAsset>("datas/" + fileName, (err, content) => {
      const { json } = content;
      if (err || !json) {
        console.error(err?.message);
        return;
      }
      const data = (json as unknown) as T;
      if (!data) {
        console.error("Json data conversion T fail: ", data);
        return;
      }
      callback(err, data);
    });
  }

  public static loadCSV2Array(fileName: string, strDelimiter?: string) {
    cc.resources.load<cc.TextAsset>("datas/" + fileName, (err, content) => {
      //cc.log('loadCSV', err, content);
      const { text } = content;

      strDelimiter = strDelimiter || ",";
      var objPattern = new RegExp(
        "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" + '(?:"([^"]*(?:""[^"]*)*)"|' + '([^"\\' + strDelimiter + "\\r\\n]*))",
        "gi"
      );
      var arrData = [[]];
      var arrMatches = null;
      while ((arrMatches = objPattern.exec(text))) {
        var strMatchedDelimiter = arrMatches[1];

        cc.log("strMatchedDelimiter===>", arrData);

        if (strMatchedDelimiter.length && strMatchedDelimiter != strDelimiter) {
          arrData.push([]);
        }
        if (arrMatches[2]) {
          var strMatchedValue = arrMatches[2].replace(new RegExp('""', "g"), '"');
        } else {
          var strMatchedValue = arrMatches[3];
        }
        arrData[arrData.length - 1].push(strMatchedValue);
      }
      if (arrData.length > 0) {
        arrData.pop();
      }
      cc.log("-------------arrData---------->", arrData);
      return arrData;
    });
  }

  public async loadPrefab(path: string) {
    return new Promise<cc.Node>((resolve, reject) => {
      cc.resources.load<cc.Prefab>(path, (err, prefab) => {
        if (err) {
          reject(err);
        } else {
          const node = instantiate(prefab);
          node.setPosition(0, 0);
          resolve(node);
        }
      });
    });
  }

  public async preload<T extends cc.Asset>(path: string) {
    return new Promise<T>((resolve, reject) => {
      cc.resources.load<T>(path, (err, asset) => {
        if (err) {
          reject(err);
        } else {
          resolve(asset);
        }
      });
    });
  }

  public releasePrefabJson(path: string) {
    cc.resources.release("prefab/" + path);
  }

  public  getItemIcon(str: string): string {
      return  "items/" + str;
  }
  public  getGambleIcon(str: string | number): string {
    return  "ui/gamble/" + str;
  }
  public  getHeadIcon(str: string | number): string {
    return  "ui/head/" + str;
  }
  public  getAssetsIcon(str: string | number): string {
    return  "ui/assets/" + str;
  }
  public  getCompanyIcon(str: string | number): string {
    return  "ui/company/" + str;
  }
  public  getActionIcon(str: string | number): string {
    return  "ui/action/" + str;
  }
  public  getHospitalIcon(str: string | number): string {
    return  "ui/hospital/" + str;
  }
  public  getDiseaseIcon(str: string | number): string {
    return  "ui/disease/" + str;
  }
  public  getSchoolIcon(str: string | number): string {
    return  "ui/school/" + str;
  }
  public  getRankIcon(str: string | number): string {
    return  "ui/rank/" + str;
  }
  
}
